<?php
namespace app;

use sql\SqlExec;
use sql\SqlWhereMerge;
use utils\SysTool;
use utils\PathTool;
use utils\CryptoTool;
use model\FileInf;
use biz\PathBuilderUuid;
use biz\FolderSchema;
use database\DBFile;
use biz\up6_biz_event;
use utils\FileBlockWriter;
use utils\WebBase;
use utils\ConfigReader;

class PageFileMgr
{    
    var $web;//WebBase
    
    function __construct($web)
    {
        $this->web = $web;
        
        $op = $web->queryString("op");
             if( strcasecmp($op,"data")==0)       $this->load_data();
        else if( strcasecmp($op,"search")==0)     $this->search();
        else if( strcasecmp($op,"rename")==0)     $this->file_rename();
        else if( strcasecmp($op,"del")==0)        $this->del();
        else if( strcasecmp($op,"del-batch")==0)  $this->del_batch();
        else if( strcasecmp($op,"uncmp-up")==0)   $this->load_uncmp_up();
        else if( strcasecmp($op,"uncmp-down")==0) $this->load_uncmp_down();
        else if( strcasecmp($op,"tree")==0)       $this->load_tree();
        else if( strcasecmp($op,"path")==0)       $this->build_path();
        else if( strcasecmp($op,"mk-folder")==0)  $this->mk_folder();
        else if( strcasecmp($op,"f_create")==0)   $this->f_create();
        else if( strcasecmp($op,"fd_create")==0)  $this->fd_create();
        else if( strcasecmp($op,"fd_data")==0)    $this->fd_data();
    }
    
    function __destruct()
    {
    }
    
    function load_tree() 
    {
        $wb = &$this->web;
        $pid = $wb->queryString("pid");        
        $swm = new SqlWhereMerge();
        $swm->equal("f_fdChild", 0);
        $swm->equal("f_fdTask", 1);
        $swm->equal("f_deleted", 0);
        if (!empty($pid)) $swm->equal("f_pid", $pid);
        
        $se = new SqlExec();
        $data = $se->select("up6_files"
            , "f_id,f_pid,f_pidRoot,f_nameLoc"
            , $swm->to_sql());
        
        //查子目录
        if (!empty($pid))
        {
            $data = $se->select("up6_folders"
                , "f_id,f_pid,f_pidRoot,f_nameLoc"
                , array("f_pid"=> $pid,
                    "f_deleted"=>false)
                );
        }
        
        $arr = array();
        for($i=0,$l=count($data);$i<$l;++$i)
        {
            $f = $data[$i];
            $item = array("id"=>$f["f_id"],"text"=>$f["f_nameLoc"],"parent"=>"#","nodeSvr"=>$f);
            $arr[] = $item;            
        }        
        die(json_encode($arr,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE));
    }
    
    function load_data()
    {
        $wb = &$this->web;
        $pid = $wb->queryString("pid");
        $isRoot = empty($pid);
        $uid = $wb->reqInt("uid");        
        $pageSize = $wb->reqInt("limit");
        $pageIndex = $wb->reqInt("page");
        if($pageSize==0) $pageSize=20;
        if($pageIndex==0) $pageIndex=1;
        $pathRel = $wb->reqStringDecode("pathRel");
        $pathRel .= '/';
        
        $swm = new SqlWhereMerge();
        //$swm->equal("f_pid", $pid);
        if(!empty($pid)) $swm->add("f_pathRel", "f_pathRel=CONCAT('$pathRel',f_nameLoc)");
        $swm->equal("f_uid", $uid);
        $swm->equal("f_complete", 1);
        $swm->equal("f_deleted", 0);
        $swm->equal("f_fdChild", 1);
        
        if($isRoot) $swm->equal("f_fdChild", 0);
        
        $where = $swm->to_sql();
        
        $se = new SqlExec();
        $data = $se->page("up6_files"
            , "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel"
            , $where
            , "f_fdTask desc,f_time desc"
            , $pageSize
            , $pageIndex);
        
        $folders = array();
        //加载子目录信息
        if(!$isRoot)
        {
            $swm->del("f_fdChild");
            
            $where = $swm->to_sql();
            $folders = $se->page("up6_folders"
                , "f_id,f_nameLoc,f_pid,f_sizeLoc,f_time,f_pidRoot,f_pathRel"
                , $where
                , "f_time desc"
                , $pageSize
                , $pageIndex);
            //设置值
            for($i=0,$l=count($folders);$i<$l;++$i)
            {
                $folders[$i]["f_fdTask"] = true;
                $folders[$i]["f_fdChild"] = false;
                $folders[$i]["f_pathSvr"] = "";
            }
        }
        
        //合并文件和目录
        $folders = array_merge($folders,$data);
        
        $count = $se->count("up6_files", $where);
        if(!$isRoot)
        {
        	$count += $se->count("up6_folders", $where);
        }
        
        $o = array();
        $o["count"] = $count;
        $o["code"]=0;
        $o["msg"]="";
        $o["data"]=$folders;
        
        die(json_encode($o,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE));
    }
    
    function search()
    {
        $wb = &$this->web;
        $pid = $wb->queryString("pid");
        $uid = $wb->reqInt("uid");
        $pageSize = $wb->reqInt("limit");
        $pageIndex = $wb->reqInt("page");
        if($pageSize==0) $pageSize=20;
        if($pageIndex==0) $pageIndex=1;
        $pathRel = $wb->reqStringDecode("pathRel");
        $pathRel .= '/';
        $key = $wb->reqStringDecode("key");
    
        $swm = new SqlWhereMerge();
        //$swm->equal("f_pid", $pid);
        if(!empty($pid)) $swm->add("f_pathRel", "f_pathRel=CONCAT('$pathRel',f_nameLoc)");
        $swm->equal("f_uid", $uid);
        $swm->equal("f_complete", 1);
        $swm->equal("f_deleted", 0);
        if(!empty($key)) $swm->add("key", "f_nameLoc like '%$key%'");
        
        $where = $swm->to_sql();
    
        $se = new SqlExec();
        $data = $se->page("up6_files"
            , "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel"
            , $where
            , "f_fdTask desc,f_time desc"
            , $pageSize
            , $pageIndex);
    
        $folders = array();
        //加载子目录信息
        $folders = $se->page("up6_folders"
            , "f_id,f_nameLoc,f_pid,f_sizeLoc,f_time,f_pidRoot,f_pathRel"
            , $where
            , "f_time desc"
            , $pageSize
            , $pageIndex);
        //设置值
        for($i=0,$l=count($folders);$i<$l;++$i)
        {
            $folders[$i]["f_fdTask"] = true;
            $folders[$i]["f_fdChild"] = false;
            $folders[$i]["f_pathSvr"] = "";
        }
    
        //合并文件和目录
        $folders = array_merge($folders,$data);
    
        $o = array();
        $o["count"] = count($folders);
        $o["code"]=0;
        $o["msg"]="";
        $o["data"]=$folders;
    
        die(json_encode($o,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE));
    }
    
    function load_uncmp_up()
    {
        $sql = "select f_id,f_md5,f_nameLoc,f_pathLoc,f_sizeLoc,f_lenSvr,f_perSvr,f_fdTask from up6_files where f_complete=0 and f_deleted=0";
        $se = new SqlExec();
        $arr = $se->exec_arr("up6_files"
            ,  $sql           
            , "f_id,f_md5,f_nameLoc,f_pathLoc,f_sizeLoc,f_lenSvr,f_perSvr,f_fdTask"
            , "id,md5,nameLoc,pathLoc,sizeLoc,lenSvr,perSvr,fdTask");
        die(json_encode($arr,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE));
    }
    
    function load_uncmp_down()
    {
        $wb = &$this->web;
        $uid = $wb->reqInt("uid");        
        
        $se = new SqlExec();
        $data = $se->select("down_files"
            , "f_id,f_nameLoc,f_pathLoc,f_perLoc,f_sizeSvr,f_fdTask"
            , array("f_uid"=>$uid));
        die(json_encode($data,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE));
    }
    
    function build_path()
    {
        $wb = &$this->web;
        $uid = $wb->reqInt("uid");
        
        $data = $_GET["data"];
        $data = urldecode($data);
        $fd = json_decode($data,true);
        
        $df = new BizFolder();
        
        die($df->build_path($fd));
    }
    
    function file_rename()
    {
        $wb = &$this->web;        
        $fdTask  = $wb->reqBool("f_fdTask");
        $pid     = $wb->queryString("f_pid");
        $id      = $wb->queryString("f_id");
        $nameNew = $wb->queryString("f_nameLoc");
        $nameNew = PathTool::urldecode_path($nameNew);
        
        $exist = false;
        $db    = new BizFolder();
        if ( !$fdTask || empty($pid)) $exist = $db->rename_file_check($nameNew, $pid);
        else $exist = $db->rename_folder_check($nameNew, $pid);
        
        //存在同名项
        if ($exist)
        {
            $res = array("state"=>false,"msg"=>"存在同名项");
            die( json_encode($res,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE) );
            return;
        }
        
        //是文件或根目录
        if ( !$fdTask || empty($pid)) 
        {           
            $se = new SqlExec();
            $inf = $se->read("up6_files", "f_pathRel", array("f_id"=>$id));
            $pathRelOld = $inf["f_pathRel"];
            $pathRelNew = $inf["f_pathRel"];
            $pos = strrpos($pathRelNew, "/");
            $pathRelNew = substr($pathRelNew, 0,$pos+1);
            $pathRelNew = $pathRelNew . $nameNew;
            
            //更新相对路径和名称
            $se->update2("up6_files", 
                array("f_pathRel"=>$pathRelNew,
                    "f_nameLoc"=>$nameNew
                ), 
                array("f_id"=>$id));
            
            //更新子文件和子目录相对路径
            if($fdTask) $this->folder_renamed($se,$pathRelNew,$pathRelOld);
        }
        else 
        {            
            $se = new SqlExec();
            $inf = $se->read("up6_folders", "f_pathRel", array("f_id"=>$id));
            $pathRelOld = $inf["f_pathRel"];
            $pathRelNew = $pathRelOld;
            $pos = strrpos($pathRelNew, "/");
            $pathRelNew = substr($pathRelNew, 0,$pos+1);
            $pathRelNew = $pathRelNew . $nameNew;
            
            //更新相对路径和名称
            $se->update2("up6_folders",
                array("f_pathRel"=>$pathRelNew,
                    "f_nameLoc"=>$nameNew
                ),
                array("f_id"=>$id));
            
            $this->folder_renamed($se,$pathRelNew,$pathRelOld);
        }
        
        $ret = array("state"=>true);
        die( json_encode($ret,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE));
    }
    
    /**
     * 文件更重命名
     * 1.更新子文件路径(pathRel)
     * 2.更新子目录路径(pathRel)
     */
    function folder_renamed($se,$pathRelNew,$pathRelOld)
    {
        //更新子文件相对路径
        $sql = "update up6_files set f_pathRel=REPLACE(f_pathRel,'$pathRelOld/','$pathRelNew/') where locate('$pathRelOld/',f_pathRel)>0";
        $se->exe_sql($sql);
        //更新子目录相对路径
        $sql = "update up6_folders set f_pathRel=REPLACE(f_pathRel,'$pathRelOld/','$pathRelNew/') where locate('$pathRelOld/',f_pathRel)>0";
        $se->exe_sql($sql);
    }
    
    function del()
    {
        $wb = &$this->web;
        $id = $wb->queryString("id");
        $pathRel = $wb->reqStringDecode("pathRel");
        $pathRel .= '/';
        
        $swm = new SqlWhereMerge();
        $swm->instr($pathRel, "f_pathRel");
        $where = $swm->to_sql();
        
        $se = new SqlExec();
        $se->update2("up6_files", array("f_deleted"=>1),array("f_id"=>$id));
        $se->update3("up6_files", array("f_deleted"=>1),$where);
        $se->update2("up6_folders", array("f_deleted"=>1),array("f_id"=>$id));
        $se->update3("up6_folders", array("f_deleted"=>1),$where);
        
        $ret = array("ret"=>1);
        die(json_encode($ret));
    }
    
    function del_batch()
    {
        $data = $_POST["data"];
        $data = urldecode($data);
        $arr = json_decode($data,TRUE);
        
        $se = new SqlExec();
        $se->exec_batch("up6_files", "update up6_files set f_deleted=1 where f_id=:f_id", null, "f_id", $arr);
        $se->exec_batch("up6_folders", "update up6_folders set f_deleted=1 where f_id=:f_id", null, "f_id", $arr);        
        
        $ret = array("ret"=>1);
        die(json_encode($ret));
    }
    
    function mk_folder()
    {
        $wb = &$this->web;
        $name    = $wb->queryString("f_nameLoc");
        $name    = PathTool::urldecode_path($name);
        $pid     = $wb->queryString("f_pid");
        $uid     = $wb->reqInt("uid");
        $pidRoot = $wb->queryString("f_pidRoot");
        $pathRel = $wb->queryString("f_pathRel");
        $pathRel = PathTool::urldecode_path($pathRel);
        $pathRel = PathTool::combin($pathRel, $name);
        
        
        $df = new BizFolder();
        if ( $df->exist_same_folder($name, $pid))
        {
            $ret = array("ret"=>false,"msg"=>"已存在同名目录");
            die( json_encode($ret,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE) );
            return;
        }
        
        $se = new SqlExec();
        $sys = new SysTool();
        $guid = $sys->guid();
        
        $fd = array("f_id"=>$guid
                    ,"f_pid"=>$pid
                    ,"f_uid"=>$uid
                    ,"f_pidRoot"=>$pidRoot
                    ,"f_nameLoc"=>$name
                    ,"f_complete"=>true
                    ,"f_fdTask"=>true
                    ,"f_pathRel"=>$pathRel
                );
        
        //根目录
        if ( empty($pid))
        {            
            $se->insert("up6_files",$fd);
        }//子目录->删除f_fdTask
        else
        {
            unset($fd["f_fdTask"]);
            $se->insert("up6_folders",$fd);
        }
        $fd["ret"]=true;
        
        die( json_encode($fd,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE) );
    }
    
    function f_create()
    {   
        $wb = &$this->web;
        
        $pid        = $wb->queryString("pid");
        $pidRoot    = $wb->queryString("pidRoot");
        if( empty($pidRoot) ) $pidRoot = $pid;//当前文件夹是根目录
        $md5 		= $wb->queryString("md5");
        $id 		= $wb->queryString("id");
        $uid 		= $wb->queryString("uid");
        $lenLoc		= $wb->queryString("lenLoc");
        $sizeLoc	= $wb->queryString("sizeLoc");
        $sizeLoc	= str_replace("+", " ", $sizeLoc);
        $callback 	= $wb->queryString("callback");
        $pathLoc	= $wb->queryString("pathLoc");
        $pathLoc	= PathTool::urldecode_path($pathLoc);
        $pathRel	= $wb->queryString("pathRel");
        $pathRel	= PathTool::urldecode_path($pathRel);
        
        if(    empty($md5)
            || strlen($uid)<1
            || empty($sizeLoc))
        {
            echo $callback . "({\"value\":null})";
            die();
        }
        
        $ext = PathTool::getExtention($pathLoc);
        $fileSvr = new FileInf();
        $fileSvr->id = $id;
        $fileSvr->pid = $pid;
        $fileSvr->pidRoot = $pidRoot;
        $fileSvr->fdChild = !empty($pid);
        $fileSvr->fdTask = false;
        $fileSvr->nameLoc = PathTool::getName($pathLoc);
        $fileSvr->pathLoc = $pathLoc;
        $fileSvr->pathRel = PathTool::combin($pathRel, $fileSvr->nameLoc);
        $fileSvr->nameSvr = $fileSvr->nameLoc;
        $fileSvr->lenLoc = intval($lenLoc);
        $fileSvr->calLenLocSec();//文件加密大小
        $fileSvr->sizeLoc = $sizeLoc;
        $fileSvr->deleted = false;
        $fileSvr->md5 = $md5;
        $fileSvr->uid = intval($uid);
        $fileSvr->encrypt = ConfigReader::storageEncrypt();//存储加密
        
        //同名文件检查
        /*$df = new BizFolder();
        if( $df->exist_same_file($fileSvr->nameLoc, $pid))
        {
            $data = "$callback({'value':'','ret':false,'code':'101','msg':'存在同名文件'})";
            die( $data);
            return;
        }*/        
        
        //生成路径
        $pb = new PathBuilderUuid();
        $fileSvr->pathSvr = $pb->genFile($uid,$fileSvr);
        $fileSvr->pathSvr = str_replace("\\", "/", $fileSvr->pathSvr);
        
        $db = new DBFile();
        $fileExist = new FileInf();
        
        //数据库存在相同文件
        if ($db->exist_file($md5, $fileExist))
        {
            $fileSvr->nameSvr = $fileExist->nameSvr;
            $fileSvr->pathSvr = $fileExist->pathSvr;
            $fileSvr->perSvr = $fileExist->perSvr;
            $fileSvr->lenSvr = intval($fileExist->lenSvr);
            $fileSvr->complete = (bool)$fileExist->complete;
            $db->Add($fileSvr);
            
            //触发事件
            up6_biz_event::file_create_same($fileSvr);            
        }//数据库不存在相同文件
        else
        {   
            //创建文件
            $fr = ConfigReader::blockWriter();
            $fileSvr->fastdfs_id = $fr->make($fileSvr);

            $db->Add($fileSvr);
            //触发事件
            up6_biz_event::file_create($fileSvr);
        }
        
        //将路径转换成相对路径
        $fileSvr->pathSvr = $pb->absToRel($fileSvr->pathSvr);
        //传输加密
        if(ConfigReader::postEncrypt())
        {
            $ct = new CryptoTool();
            $fileSvr->pathSvr = $ct->encrypt($fileSvr->pathSvr);
        }
        
        $json = json_encode($fileSvr,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE);//
        
        $json = urlencode($json);
        $json = str_replace("+","%20",$json);
        $json = $callback . "({'value':'$json','ret':true})";//返回jsonp格式数据。
        die( $json );
    }
    
    function f_post(){}
    function f_complete(){}
    function f_del(){}
    function fd_create()
    {
        $wb = &$this->web;
        
        $id 		= $wb->queryString("id");
        $pid 		= $wb->queryString("pid");
        $pidRoot	= $wb->queryString("pidRoot");
        if( empty($pidRoot)) $pidRoot = $pid;//父目录是根目录
        $uid 		= $wb->queryString("uid");
        $lenLoc		= $wb->queryString("lenLoc");
        $sizeLoc	= $wb->queryString("sizeLoc");
        $sizeLoc	= str_replace("+", " ", $sizeLoc);
        $callback 	= $wb->queryString("callback");
        $pathLoc	= $wb->queryString("pathLoc");
        $pathLoc	= PathTool::urldecode_path($pathLoc);
        $pathRel	= $wb->queryString("pathRel");
        $pathRel	= PathTool::urldecode_path($pathRel);
        
        if(    empty($id)
            || strlen($uid)<1
            || empty($pathLoc))
        {
            echo $id;
            echo $uid;
            echo $pathLoc;
            echo $callback . "({\"value\":null})";
            die();
        }
        
        $fileSvr = new FileInf();
        $fileSvr->id = $id;
        $fileSvr->pid = $pid;
        $fileSvr->pidRoot = $pidRoot;
        $fileSvr->fdChild = !empty($pid);
        $fileSvr->fdTask = true;
        $fileSvr->uid = intval($uid);
        $fileSvr->nameLoc = PathTool::getName($pathLoc);
        $fileSvr->pathLoc = $pathLoc;
        $fileSvr->pathRel = PathTool::combin($pathRel, $fileSvr->nameLoc);
        $fileSvr->lenLoc = intval($lenLoc);
        $fileSvr->sizeLoc = $sizeLoc;
        $fileSvr->deleted = false;
        $fileSvr->nameSvr = $fileSvr->nameLoc;
        
        //同名目录检查
        $df = new BizFolder();
        /*if( $df->exist_same_folder($fileSvr->nameLoc, $pid))
        {
            $data = "$callback({'value':'','ret':false,'code':'101',msg:'存在同名目录'})";
            die( $data);
            return;
        }*/
        
        //生成路径
        $pb = new PathBuilderUuid();
        $fileSvr->pathSvr = $pb->genFolder($fileSvr);
        $fileSvr->pathSvr = str_replace("\\", "/", $fileSvr->pathSvr);
        
        //创建层级信息文件
        $fs = new FolderSchema();
        $fs->create($fileSvr);
        
        $db = new DBFile();
        if(empty($pid)) $db->Add($fileSvr);
        else $df->addChildFolder($fileSvr);
        
        //加密
        $cr = new ConfigReader();
        $sec = $cr->module("path");
        $encrypt = $sec->get("$.security.encrypt")[0];
        if($encrypt)
        {
            $ct = new CryptoTool();
            $fileSvr->pathSvr = $ct->encrypt($fileSvr->pathSvr);
        }
        
        up6_biz_event::folder_create($fileSvr);
        
        $json = json_encode($fileSvr,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE);//低版本php中，json_encode会将汉字进行unicode编码
        $json = urlencode($json);
        
        $json = str_replace("+","%20",$json);
        $json = $callback . "({'value':'$json','ret':true})";//返回jsonp格式数据。
        die( $json );
    }
    function fd_complete(){}
    function fd_del(){}
    function fd_data()
    {
        $wb = &$this->web;
        $id 		= $wb->queryString("id");
        $callback 	= $wb->queryString("callback");//jsonp
    
        if(empty($id))
        {
            echo $callback . "({\"value\":null})";
            die();
        }
    
        $fb = new FolderBuilder();
        $data = $fb->build($id);    
        $json = json_encode($data,JSON_UNESCAPED_SLASHES| JSON_UNESCAPED_UNICODE);//
    
        $json = urlencode($json);
        $json = str_replace("+","%20",$json);
        $json = $callback . "({'value':'$json'})";//返回jsonp格式数据。
        die( $json );
    }
}
?>